package com.apes.fn.mdm.supplierConfiguration;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.outbox.OutboxPayloadWrapper;
import com.apes.framework.plugin.outbox.OutboxSubscriberService;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.pi.service.PiManager;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.product.model.Classify;
import com.apes.scm.masterdata.product.repository.ClassifyRepository;
import com.apestech.framework.util.DateUtil;
import com.apestech.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author yiny
 * @date 2021.4.13
 */
@Service("supplierBusinessScopeService")
public class SupplierBusinessScopeService {
    @Autowired
    private SupplierBusinessScopeRepository supplierBusinessScopeRepository;
    @Autowired
    private PiManager piManager;
    @Autowired
    private OutboxSubscriberService outboxSubscriberService;
    @Autowired
    private EnumerationRepository enumerationRepository;
    @Autowired
    private SupplierBrandRepository supplierBrandRepository;
    @Autowired
    private ClassifyRepository classifyRepository;

    public SupplierBusinessScope save(SimpleRequest request) {
        SupplierBusinessScope supplierBusinessScope = request.getO(SupplierBusinessScope.class);
        List<SupplierBusinessScope> supplierBusinessScopeList = supplierBusinessScopeRepository.findAll(JpaDsl.toCriteriaByEq("supplierId.id", supplierBusinessScope.getSupplierId().getId()));
        if (supplierBusinessScopeList.size() > 0) throw new RuntimeException("该供应商已存在！");

        supplierBusinessScope = supplierBusinessScopeRepository.saveAndFlush(supplierBusinessScope);
        this.synSupplierBusinessScopeDataToOld(supplierBusinessScope);
        return supplierBusinessScope;
    }

    public SupplierBusinessScope update(SimpleRequest request) {
        SupplierBusinessScope supplierBusinessScope = request.getO(SupplierBusinessScope.class);
        supplierBusinessScope = supplierBusinessScopeRepository.saveAndFlush(supplierBusinessScope);
        if (StringUtils.hasText(supplierBusinessScope.getDefualtSupplierOperator()))
            this.synCZYZT(supplierBusinessScope.getOperatorStatus().getCode(), supplierBusinessScope.getDefualtSupplierOperator(), supplierBusinessScope.getSupplierId().getParty().getOrigin());
        this.synSupplierBusinessScopeDataToOld(supplierBusinessScope);
        return supplierBusinessScope;
    }


    /**
     * 供应商经营范围同步老框架
     *
     * @param supplierBusinessScope
     */
    public void synSupplierBusinessScopeDataToOld(SupplierBusinessScope supplierBusinessScope) {
        JSONObject data = new JSONObject();
        data.put("ORIGIN", supplierBusinessScope.getSupplierId().getParty().getOrigin());
        data.put("SUPPLIER_ID", supplierBusinessScope.getSupplierId().getId());
        data.put("SUPPLIER_SUSINESS_SCOPEE_ID", supplierBusinessScope.getId());

        if (supplierBusinessScope.getSupplierClassifies().size() != 0 && supplierBusinessScope.getSupplierClassifies().get(0) != null) {
            AtomicReference supplierClassifyId = new AtomicReference("'',");
            supplierBusinessScope.getSupplierClassifies().forEach(supplierClassify -> {
                supplierClassifyId.set(supplierClassifyId.get() + "'" + supplierClassify.getId() + "',");
            });
            data.put("SUPPLIER_CLASSIFY_ID", supplierClassifyId.get().toString().substring(0, supplierClassifyId.get().toString().length() - 1));
        } else {
            data.put("SUPPLIER_CLASSIFY_ID", "");
        }

     /*   勿删
        data.put("ID", supplierBusinessScope.getId());
        data.put("INSTALL_SUPPLIER", supplierBusinessScope.getInstallSupplier());
        data.put("PUSH_SINGLE_CALENDAR", supplierBusinessScope.getPushSingleCalendar());
        data.put("SUPPLIER_TAX", supplierBusinessScope.getSupplierTax());
        data.put("DEFUALT_SUPPLIER_OPERATOR", supplierBusinessScope.getDefualtSupplierOperator());
        data.put("DEFUALT_SUPPLIER_OPERATOR_NAME", supplierBusinessScope.getDefualtSupplierOperatorName());
        data.put("SUPPLIER_ID", supplierBusinessScope.getSupplierId().getParty().getOrigin());


        // 供应商品类
        JSONArray supplierClassifyArray = new JSONArray();
        supplierBusinessScope.getSupplierClassifies().forEach(supplierClassify -> {
            JSONObject supplierClassifyObj = new JSONObject();
            supplierClassifyObj.put("ID", supplierClassify.getId());
            supplierClassifyObj.put("CLASSIFY_ID", supplierClassify.getClassifyId().getId());
            supplierClassifyObj.put("SUPPLIER_SUSINESS_SCOPEE_ID", supplierClassify.getSupplierBusinessScopeId().getId());
            supplierClassifyArray.add(supplierClassifyObj);

            // 排除项
            JSONArray excludeClassifyArray = new JSONArray();
            supplierClassify.getExcludeClassify().forEach(v -> {
                JSONObject excludeClassifyObj = new JSONObject();
                excludeClassifyObj.put("CLASSIFY_ID", v.getId());
                excludeClassifyObj.put("SUPPLIER_CLASSIFY_ID", supplierClassify.getId());
                excludeClassifyArray.add(excludeClassifyObj);
                System.out.println("---------------");
            });
        });
        data.put("MAS_SUPPLIER_CLASSIFY", supplierClassifyArray);


        // 供应商厂牌
        JSONArray supplierBrandArray = new JSONArray();
        supplierBusinessScope.getSupplierBrands().forEach(supplierBrand1 -> {
            JSONObject supplierBrand = new JSONObject();
            supplierBrand.put("ID", supplierBrand1.getId());
            supplierBrand.put("CARLABEL_ID", supplierBrand1.getCarLabelId().getId());
            supplierBrand.put("SUPPLIER_SUSINESS_SCOPEE_ID", supplierBrand1.getSupplierBusinessScopeId().getId());
            supplierBrandArray.add(supplierBrand);
        });
        data.put("MAS_SUPPLIER_BRAND", supplierBrandArray);*/
        outboxSubscriberService.commonSendRequest("local:supplierBusinessScopeService.synSupplierBusinessScopeData", "供应商经营范围同步老框架" + supplierBusinessScope.getSupplierId().getId(), data);
        System.out.println();
    }


    /**
     * 同步供应商账号权限
     *
     * @param request
     */
    public SupplierBusinessScope synSupplierLimit(SimpleRequest request) {
        SupplierBusinessScope supplierBusinessScope = request.getO(SupplierBusinessScope.class);
        String defualtSupplierOperator = supplierBusinessScope.getDefualtSupplierOperator();
        String defualtSupplierOperatorName = supplierBusinessScope.getDefualtSupplierOperatorName();

        Map mapCondi = new HashMap();
        mapCondi.put("ID", supplierBusinessScope.getId());
        List getOpertors = supplierBusinessScopeRepository.findAll("SELECT * FROM MAS_SUPPLIER_BUSINESS_SCOPE WHERE ID = :ID AND DEFUALT_SUPPLIER_OPERATOR IS NOT NULL", mapCondi);
        if (getOpertors.size() != 0) throw new RuntimeException("操作员编码重复，账号已存在");

        JSONObject condi = new JSONObject();
        condi.put("GYSID", supplierBusinessScope.getSupplierId().getParty().getOrigin());
        condi.put("CZYID", defualtSupplierOperator);
        condi.put("CZYMC", defualtSupplierOperatorName);
        condi.put("CZYZT", supplierBusinessScope.getOperatorStatus().getCode());
        JSONObject responseData = piManager.synErp("autBdqxService.queryCZYInfo", condi);
        responseData = JSONObject.parseObject(responseData.get("obj").toString());
        if (responseData != null) {
            mapCondi.put("DEFUALT_SUPPLIER_OPERATOR", responseData.get("CZYID"));
            mapCondi.put("DEFUALT_SUPPLIER_OPERATOR_NAME", responseData.get("CZYMC"));

            int czyzt = responseData.getInteger("CZYZT");
            List<Enumeration> operatorStates = enumerationRepository.findAll(JpaDsl.toCriteriaByEq("type.id", "operatorStatus", "code", czyzt));
            if (operatorStates.size() != 0) mapCondi.put("operatorStatus", operatorStates.get(0).getId());
        } else {
            mapCondi.put("DEFUALT_SUPPLIER_OPERATOR", defualtSupplierOperator);
            mapCondi.put("DEFUALT_SUPPLIER_OPERATOR_NAME", defualtSupplierOperatorName);
            mapCondi.put("operatorStatus", supplierBusinessScope.getOperatorStatus().getId());
        }
        String sql = "UPDATE MAS_SUPPLIER_BUSINESS_SCOPE SET DEFUALT_SUPPLIER_OPERATOR = :DEFUALT_SUPPLIER_OPERATOR, DEFUALT_SUPPLIER_OPERATOR_NAME = :DEFUALT_SUPPLIER_OPERATOR_NAME, OPERATOR_STATUS = :operatorStatus WHERE ID = :ID";
        supplierBusinessScopeRepository.exec(sql, mapCondi);
        if (StringUtils.isEmpty(condi.get("CZYMC"))) throw new RuntimeException("请填写供应商名称！");
        if (responseData == null)
            outboxSubscriberService.commonSendRequest("local:supplierBusinessScopeService.synSupplierLimit", "急件供应商创建供应商账号" + supplierBusinessScope.getSupplierId().getId(), condi);
        return supplierBusinessScopeRepository.findOne(supplierBusinessScope.getId());
    }

    private void synCZYZT(String czyzt, String czyid, String gysid) {
        JSONObject data = new JSONObject();
        data.put("CZYZT", czyzt);
        data.put("CZYID", czyid);
        outboxSubscriberService.commonSendRequest("local:supplierBusinessScopeService.synCZYZT", "急件供应商修改供应商账号" + gysid, data);
    }

    /**
     * 旧框架修改状态
     */
    public void synOldCZYZT(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        Map condi = request.getMap();
        if (supplierBusinessScopeRepository.findAll("SELECT * FROM MAS_SUPPLIER_BUSINESS_SCOPE WHERE DEFUALT_SUPPLIER_OPERATOR = :CZYID", condi).size() == 0)
            return;

        int czyzt = Integer.parseInt(condi.get("CZYZT").toString());
        List<Enumeration> operatorStates = enumerationRepository.findAll(JpaDsl.toCriteriaByEq("type.id", "operatorStatus", "code", czyzt));
        if (operatorStates.size() != 0) condi.put("CZYZT", operatorStates.get(0).getId());
        condi.remove("TYPE");
        String sql = "UPDATE MAS_SUPPLIER_BUSINESS_SCOPE SET DEFUALT_SUPPLIER_OPERATOR_NAME = :CZYMC, OPERATOR_STATUS = :CZYZT WHERE DEFUALT_SUPPLIER_OPERATOR = :CZYID";

        if ("D".equals(getJO.getString("TYPE"))) {
            sql = "UPDATE MAS_SUPPLIER_BUSINESS_SCOPE SET DEFUALT_SUPPLIER_OPERATOR = null, DEFUALT_SUPPLIER_OPERATOR_NAME = null, OPERATOR_STATUS = null WHERE DEFUALT_SUPPLIER_OPERATOR = '" + condi.get("CZYID") + "'";
            supplierBusinessScopeRepository.exec(sql);
            return;
        }
        supplierBusinessScopeRepository.exec(sql, condi);
    }

    /**
     * 查询供应商是否装机推单
     */
    public boolean judgeInstallSupplier(String supplierId) {
        String sql = "" +
                "SELECT DISTINCT SUPPLIER_ID " +
                "  FROM MAS_SUPPLIER_BUSINESS_SCOPE A " +
                " WHERE INSTALL_SUPPLIER = 1 " +
                "   AND PUSH_SINGLE_CALENDAR LIKE " +
                "       '%' || (select to_char(sysdate, 'day', 'NLS_DATE_LANGUAGE=''SIMPLIFIED CHINESE''') from dual) || '%' " +
                "   AND SUPPLIER_ID IN ('" + supplierId + "')";
        return supplierBusinessScopeRepository.findAll(sql).size() != 0;
    }

    // 根据供应商获取到需要排除的品类
    public List accordSupplierFindExcludeClassify(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        String carlabelId = getJO.getString("carlabelId");
        String supplierId = getJO.getString("supplierId");

        // 无厂牌表示所有的车型都需要排除
        List excluClassifys = new ArrayList();
        List<SupplierBusinessScope> supplierBusinessScopes = new ArrayList<>();
        List<SupplierBrand> supplierBrands = supplierBrandRepository.accordingCarlabelIdFind(carlabelId);
        if (!supplierBrands.isEmpty()) {
            supplierBusinessScopes = supplierBusinessScopeRepository.accordingSupplierFind(supplierBrands.get(0).getSupplierBusinessScopeId().getSupplierId().getId());
        } else {
            supplierBusinessScopes = supplierBusinessScopeRepository.accordingSupplierFind(supplierId);
        }

        if (supplierBusinessScopes.isEmpty()) return excluClassifys;
        supplierBusinessScopes.get(0).getSupplierClassifies().forEach(supplierClassifies -> {
            supplierClassifies.getExcludeClassify().forEach(excludeClassify -> {
                excluClassifys.add(excludeClassify.getId());
            });
        });
        return excluClassifys;
    }

    // 判断是否存在需要排除的品类
    public boolean existsExcluClassify(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        String proClassify = getJO.getString("proClassify");
        JSONArray classifyId = getJO.getJSONArray("excluClassifys");
        return classifyId.stream().anyMatch(excludeClassifyId -> {
            return proClassify.indexOf(excludeClassifyId.toString()) != -1;
        });
    }

    @OutboxSubscriber(id = "local:supplierBusinessScopeService.synSupplierLimit", name = "急件供应商创建供应商账号")
    private void piSynSupplierLimit(OutboxPayloadWrapper outboxPayloadWrapper) {
        JSONObject resultObj = piManager.synErp("autBdqxService.insertSupplierConfigurationSynLimit", outboxPayloadWrapper.getPayload());
    }

    @OutboxSubscriber(id = "local:supplierBusinessScopeService.synCZYZT", name = "急件供应商修改供应商账号")
    private void piSynCZYZT(OutboxPayloadWrapper outboxPayloadWrapper) {
        JSONObject resultObj = piManager.synErp("autCzyService.updateCZYZT", outboxPayloadWrapper.getPayload());
    }

    @OutboxSubscriber(id = "local:supplierBusinessScopeService.synSupplierBusinessScopeData", name = "供应商经营范围同步老框架")
    private void synSupplierBusinessScopeData(OutboxPayloadWrapper outboxPayloadWrapper) {
        JSONObject resultObj = piManager.synErp("mdmGysjyfwService.synNewFrameGYSJYFW", outboxPayloadWrapper.getPayload());
    }

    // 外部调用，厂牌判断
    public boolean externalCallBusinessScopeCar(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        return this.ifSupplierBusinessScope(getJO.getString("supplierId"), getJO.getString("carlabelId"));
    }

    // 外部调用，品类判断
    public boolean externalCallBusinessScopeClassify(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        String supplierId = getJO.getString("supplierId");
        String classifyId = getJO.getString("classifyId");
        Classify classify = classifyRepository.findOne(classifyId);

        boolean ifExcludeOfClassifyFlag = this.ifExcludeOfClassify(supplierId, classify);
//        if (ifExcludeOfClassifyFlag) return true;

        return this.ifSupplierRunClassify(supplierId, classify) && ifExcludeOfClassifyFlag;
    }

    /**
     * 根据供应商和经营厂牌判断是否经营
     *
     * @param supplierId 供应商id
     * @param carLabel   厂牌id
     * @return 是否经营
     */
    public boolean ifSupplierBusinessScope(String supplierId, String carLabel) {
        SupplierBusinessScope supplierBusinessScope = supplierBusinessScopeRepository.findBySupplierId(supplierId);
        if (Objects.isNull(supplierBusinessScope)) return false;
        if (supplierBusinessScope.getSupplierBrands().isEmpty()) return true;
        List<SupplierBrand> supplierBrands = supplierBusinessScope.getSupplierBrands();
        List<String> supplierBrandId = supplierBrands.stream().map(supplierBrand -> supplierBrand.getCarLabelId().getId()).collect(Collectors.toList());
        return supplierBrandId.contains(carLabel);
    }

    /**
     * 根据供应商和品类判断是否经营
     *
     * @param supplier  供应商id
     * @param classify 品类
     * @return 是否经营
     */
    public boolean ifSupplierRunClassify(String supplier, Classify classify) {
        SupplierBusinessScope supplierBusinessScope = supplierBusinessScopeRepository.findBySupplierId(supplier);
        if (Objects.isNull(supplierBusinessScope)) return false;
        List<SupplierClassify> supplierClassifies = supplierBusinessScope.getSupplierClassifies();
        if (supplierClassifies.isEmpty()) return true;//没有经营品类则是全部经营
        List<String> supplierClassifyId = supplierClassifies.stream().map(supplierClassify -> supplierClassify.getClassifyId().getId()).collect(Collectors.toList());

        return Objects.nonNull(parts(classify, supplierClassifyId));
    }

    /**
     * 根据供应商和品类判断是否经营
     *
     * @param supplierBusinessScope  急件供应商
     * @param classify 品类
     * @return 是否经营
     */
    public boolean ifSupplierRunClassify(SupplierBusinessScope supplierBusinessScope, Classify classify) {
        List<SupplierClassify> supplierClassifies = supplierBusinessScope.getSupplierClassifies();
        if (supplierClassifies.isEmpty()) return true;//没有经营品类则是全部经营
        List<String> supplierClassifyId = supplierClassifies.stream().map(supplierClassify -> supplierClassify.getClassifyId().getId()).collect(Collectors.toList());

        return Objects.nonNull(parts(classify, supplierClassifyId));
    }

    /**
     * 根据供应商和品类id排除
     * @param supplier
     * @param classify
     * @return false:排除  true:不排除
     */
    public boolean ifExcludeOfClassify(String supplier, Classify classify) {
        SupplierBusinessScope supplierBusinessScope = supplierBusinessScopeRepository.findBySupplierId(supplier);
        if (Objects.isNull(supplierBusinessScope)) return false;
        if (supplierBusinessScope.getSupplierClassifies().isEmpty()) return true;//不排除
        for (SupplierClassify supplierClassify : supplierBusinessScope.getSupplierClassifies()) {
            List<String> excludeClassifies = supplierClassify.getExcludeClassify().stream().map(Classify::getId).collect(Collectors.toList());
            if (excludeClassifies.isEmpty())continue;//跳过没有排除项的
            if (Objects.nonNull(parts(classify,excludeClassifies))){//成立一次就是需要排除
                return false;
            }
        }
        return true;//不排除
    }

    /**
     * 根据急件供应商和品类id排除
     * @param supplierBusinessScope
     * @param classify
     * @return false:排除  true:不排除
     */
    public boolean ifExcludeOfClassify(SupplierBusinessScope supplierBusinessScope, Classify classify) {
        if (supplierBusinessScope.getSupplierClassifies().isEmpty()) return true;//不排除
        for (SupplierClassify supplierClassify : supplierBusinessScope.getSupplierClassifies()) {
            List<String> excludeClassifies = supplierClassify.getExcludeClassify().stream().map(Classify::getId).collect(Collectors.toList());
            if (excludeClassifies.isEmpty())continue;//跳过没有排除项的
            if (Objects.nonNull(parts(classify,excludeClassifies))){//成立一次就是需要排除
                return false;
            }
        }
        return true;//不排除
    }


    private Classify parts(Classify classify, List<String> supplierClassifyId){
        if (Objects.isNull(classify))return classify;
        if (supplierClassifyId.contains(classify.getId())) return classify;
        return parts(classify.getParents(),supplierClassifyId);
    }

    /**
     * 供应商推单日历
     * @param supplier 供应商id
     * @return 供应商当天是否经营
     */
    public boolean isOperationTime(String supplier) {
        SupplierBusinessScope supplierBusinessScope = supplierBusinessScopeRepository.findBySupplierId(supplier);
        if (Objects.isNull(supplierBusinessScope)) return false;//没有配件急件供应商
        JSONArray pushSingleCalendar = JSONArray.parseArray(supplierBusinessScope.getPushSingleCalendar());
        if (pushSingleCalendar.isEmpty()) return true;//不配置代表全部经营
        List<Integer> operationTime = pushSingleCalendar.toJavaList(JSONObject.class).stream().map(item -> item.getInteger("id")).collect(Collectors.toList());
        int week = DateUtil.dayOfWeek(new Date());
        if (week == 1){
            week = 7;
        }else {
            --week;
        }
        return operationTime.contains(week);
    }
}


























